﻿using Serilog;
using Serilog.Events;
using Serilog.Formatting.Compact;

namespace SysLog;

public class ILog 
{
    private static ILogger _logger;
    // MySQL 连接信息
    private const string Server = "localhost";
    private const int Port = 3307;
    private const string Database = "logs";
    private const string UserId = "root";
    private const string Password = "123456";
    
    private static string ConnectionString => 
        $"Server={Server};Port={Port};Database={Database};Uid={UserId};Pwd={Password};";
    private const string TableName = "appLogs";
    
    public static void writeError(string? message)
    {
        _logger.Write(LogEventLevel.Error, message);
    }
    
    public static void writeInfo(string message)
    {
        _logger.Write(LogEventLevel.Information, message);
    }
    
    public static void ConfigureSerilog()
    {
        // 日志文件路径（自动创建日志目录）
        var logDirectory = "Logs";
        var logFilePath = $"{logDirectory}/log-.txt";
        
        // 创建日志配置
        _logger = new LoggerConfiguration()
            // 最小日志级别设置
            .MinimumLevel.Debug()
            
            // 覆盖特定命名空间的日志级别
            .MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
            
            // 控制台输出配置
            .WriteTo.Console(
                restrictedToMinimumLevel: LogEventLevel.Information,
                outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}"
            )
            
            // 文件输出配置 - 普通文本格式
            .WriteTo.File(
                path: logFilePath,
                restrictedToMinimumLevel: LogEventLevel.Debug,
                rollingInterval: RollingInterval.Day,      // 每天创建新文件
                retainedFileCountLimit: 7,                // 保留最近7天的日志
                fileSizeLimitBytes: 10 * 1024 * 1024,     // 单个文件最大10MB
                rollOnFileSizeLimit: true,                // 达到大小限制时创建新文件
                outputTemplate: "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} {Level:u3}] {Message:lj}{NewLine}{Exception}"
            )
            
            // 文件输出配置 - JSON格式（可选）
            .WriteTo.File(
                path: $"{logDirectory}/json-log-.json",
                formatter: new CompactJsonFormatter(),    // 使用紧凑JSON格式
                rollingInterval: RollingInterval.Day,
                retainedFileCountLimit: 7
            )
            .CreateLogger();
    }

    public static void ConfigureSerilogToMysql()
    {
        try
        {
            //初始化日志数据库
            CreateLogTableIfNotExists();
            // 创建日志配置
            _logger = new LoggerConfiguration()
                // 最小日志级别设置
                .MinimumLevel.Debug()

                // 覆盖特定命名空间的日志级别
                .MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
                .WriteTo.MySQL(
                    connectionString: ConnectionString,
                    tableName: TableName,
                    storeTimestampInUtc: false,
                    batchSize: 100, // 每批100条日志
                    restrictedToMinimumLevel: LogEventLevel.Information
                )
                .CreateLogger();
        }
        catch (Exception e)
        {
            if (e.StackTrace != null) writeError(e.StackTrace);
        }
    }
    
    private static void CreateLogTableIfNotExists()
    {
        try
        {
            var createTableSql = $@"
            CREATE TABLE IF NOT EXISTS `{TableName}` (
                `Id` BIGINT AUTO_INCREMENT PRIMARY KEY,
                `Timestamp` DATETIME(6) NOT NULL,
                `Level` VARCHAR(20) NOT NULL,
                `Message` TEXT,
                `MessageTemplate` TEXT,
                `Exception` TEXT,
                `Properties` JSON,
                `MachineName` VARCHAR(50),
                `UserName` VARCHAR(50),
                `AppVersion` VARCHAR(20)
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
            ";

            using var connection = new MySql.Data.MySqlClient.MySqlConnection(ConnectionString);
            connection.Open();
            using var command = new MySql.Data.MySqlClient.MySqlCommand(createTableSql, connection);
            command.ExecuteNonQuery();
            
            Log.Logger.Debug("MySQL 日志表已创建或已存在");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"创建日志表失败: {ex.Message}");
        }
    }
}